use std::{rc::Rc, cell::RefCell};

use crate::{instructions::base::{Instruction, BytecodeReader}, rtda::{Frame, heap::Class}};

// 需要两个操作数。
// 第一个操作数是uint16索引，来自字节码。通过这个索引可以从当前类的运行时常量池中找到一个类符号引用，解析这个符号引用就可以得到数组元素的类。
// 第二个操作数是数组长度，从操作数栈中弹出。
#[derive(Debug, Default)]
pub struct ANEW_ARRAY {
    index: usize
}

impl Instruction for ANEW_ARRAY {
    fn fetch_operands(&mut self, reader: &mut BytecodeReader) {
        self.index = reader.read_u16() as usize;
    }

    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let cp = frame.borrow().get_method().get_class().get_constant_pool().unwrap();
        let class_ref = cp.get_constant(self.index).unwrap().class_ref();
        // 数组元素类
        let component_class = class_ref.lock().unwrap().resolved_class();

        let stack = frame.borrow().get_operand_stack();
        // 数组长度
        let count = stack.borrow_mut().pop_int();
        if count < 0 {
            panic!("java.lang.NegativeArraySizeException");
        }
        let arr_class = component_class.array_class();
        let arr = Class::new_array(arr_class, count as usize);
        stack.borrow_mut().push_ref(Some(Box::into_raw(Box::new(arr))));
        
    }

}